# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: donggu

import pygit2
from github import Github
import os
import json
import sys
import neptune

if len(sys.argv) < 2:
  import sys
  print('provide exp_name (e.g. v0610i)')
  sys.exit(1)

username = 'bot-ci@prestolabs.io'
password = 'M@PdzHCySSuu2'
exp_name = sys.argv[1]

if len(sys.argv) == 6:
  rev_coin = ' | '.join(sys.argv[2].split(' ', 1))
  rev_coin_binary = ' | '.join(sys.argv[3].split(' ', 1))
  rev_coin_deploy = ' | '.join(sys.argv[4].split(' ', 1))
  rev_lm_export = ' | '.join(sys.argv[5].split(' ', 1))

  revisions = ('Commit | Commit\n'
               '---- | --------\n'
               f'{rev_coin}\n'
               f'{rev_coin_binary}\n'
               f'{rev_coin_deploy}\n'
               f'{rev_lm_export}\n')
else:
  revisions = ''

credentials = pygit2.UserPass(username, password)
callbacks = pygit2.RemoteCallbacks(credentials=credentials)


# [(config_path, symbol, config value)]
def get_changelist():
  name_filter = sys.argv[1]

  session = neptune.sessions.Session.with_default_backend().get_project('donggu-prestolabs/lm-agg2')

  leaderboard_df = session.get_leaderboard()
  ids = leaderboard_df[leaderboard_df.name == name_filter].id.values
  exps = session.get_experiments(id=ids)

  changes = []
  for exp in exps:
    print('processing ', exp.id, exp.name)
    prop = exp.get_properties()

    # python/coin_deploy/lm_agg2/config_coin1_style/lab/usdt/lm_agg_okex_futures_allexpiry_btc.json
    original_config_path = prop['original_config']
    original_config_path = original_config_path[len('python/coin_deploy/'):]

    exchange = prop['exchange']
    symbol = prop['target']
    exp_dir = f'out/{exp.name}-{exchange}-{symbol}'

    # until we impl
    # best_trial = prop['best_trial']

    if 'best_trial' not in prop:
      continue

    best_trial = prop['best_trial']

    # download config and read original / best params
    exp.download_artifact(f'configs/Trial_{best_trial}.json', exp_dir)
    product_config = json.loads(
        open(f'{exp_dir}/Trial_{best_trial}.json').read())['products'][symbol]

    changes.append((original_config_path, exchange, symbol, product_config))
  return changes


def github():
  change_list = get_changelist()

  g = Github(username, password)
  repo = g.get_repo("prestolabs/coin_deploy")
  master = repo.get_branch('master')
  try:
    repo.create_git_ref(ref='refs/heads/' + exp_name, sha=master.commit.sha)
  except Exception:
    pass

  for (config_path, exchange, symbol, value) in change_list:
    contents = repo.get_contents(config_path, ref=exp_name)
    config = json.loads(contents.decoded_content)
    config['products'][symbol] = value

    repo.update_file(contents.path,
                     f"update {exchange} {symbol}",
                     json.dumps(config, indent=2),
                     contents.sha,
                     branch=exp_name)

  report_url = f'http://donggu-work.sg.corp.prestolabs.io:8080/report_{exp_name}.html'
  body = f'<a href="{report_url}">The report</a>\n\n{revisions}'
  try:
    repo.create_pull(title="Auto lm-agg2 Update: " + exp_name,
                     body=body,
                     head=exp_name,
                     base="master")
  except Exception:
    pass


def checkout_and_commit():
  tmp_dir = '/tmp/coin_deploy'

  repo = pygit2.clone_repository('https://github.com/prestolabs/coin_deploy.git',
                                 tmp_dir,
                                 callbacks=callbacks)

  for (config_path, symbol, value) in get_changelist():
    path = os.path.join(tmp_dir, config_path)
    config = json.load(open(path, 'r'))
    config['products'][symbol] = value
    json.dump(config, open(path, 'w'), indent=2)

  repo.index.add_all()
  tree = repo.index.write_tree()
  author = pygit2.Signature('Bot Ci', 'bot-ci@prestolabs.io')
  committer = pygit2.Signature('Bot Ci', 'bot-ci@prestolabs.io')

  repo.branches.create(exp_name, repo.head.peel())
  repo.create_commit(f'refs/heads/{exp_name}', author, committer, 'msg', tree, [repo.head.target])
  # repo.create_commit(None, author, committer, 'msg', tree, [])
  repo.set_head(f'refs/heads/{exp_name}')

  return repo


def push(repo):
  remote = repo.remotes["origin"]
  remote.credentials = credentials
  remote.push(['refs/heads/{exp_name}'], callbacks=callbacks)


github()
